# 作业：
# 1、通过python连接pymysql数据库，封装类方法
# 1.1、随机插入100条数据到数据库表，包括姓名、年龄、家庭住址、身份证号码
# 1.2、查询全部的数据
# 1.3、删除指定一条数据
# 1.4、封装批量删除方法，可以删除多条
# 1.5、可以指定增加单独一条数据到表里
# 以上每个操作步骤要写日志信息到log.txt里
# create table stu(id int primary key auto_increment,name varchar(20) not null,age int,address varchar(50) default '沈阳',ssn varchar(50));
import random
import traceback
import pymysql
from faker import Faker
from random import randint      # 年龄
from datetime import datetime
class DB:
    faker = Faker(locale='zh_cn')
    def connect(self):
        self.db = pymysql.connect(user='root',password='1965331442Xby@',database='ying',host='47.99.105.120',cursorclass =
        pymysql.cursors.DictCursor)
        # 创建游标
        self.cursor = self.db.cursor()
    # 关闭数据库方法
    def close(self):
        self.cursor.close()
        self.db.close()
class Stu(DB):
    # create table stu(id int primary key auto_increment,name varchar(20) not null,age int,address varchar(50) default '沈阳',ssn varchar(50));
    def insertRow(self,row:int=100):
        # 姓名、年龄、家庭住址、身份证号码
        self.connect()
        # 定义一个写入日志的列表
        result = ["当前时间为：" + str(datetime.now()) +f"当前执行插入数据操作，插入数据：{row}条"+"\n"]
        try:
            for i in range(row):
                # 姓名
                name = self.faker.name()
                # 年龄
                age = randint(18,99)
                # 身份证
                ssn = self.faker.ssn(min_age=18,max_age=99)
                # 家庭住址
                address = self.faker.address()
                sql_obj = f"insert into stu(name,age,address,ssn) values('{name}','{age}','{address}','{ssn}')"
                result.append(sql_obj+"\n")
                self.cursor.execute(sql_obj)
                print("当前新增的信息，姓名为：{}，年龄是：{}，住址是：{}，身份证号码是：{}".format(name,age,address,ssn))
            self.db.commit()
            with open('logs.txt','a',encoding='utf-8') as f:
                f.writelines(result)
        except:
            # 报错先回滚
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()

    # 1.2、查询全部的数据
    def searchAll(self):
        self.connect()
        result = ["当前时间为：" + str(datetime.now()) +f"当前执行查看全部数据操作"+"\n"]
        try:
            self.cursor.execute('select * from stu')
            all_data = self.cursor.fetchall()
            for row,value in enumerate(all_data):
                print(f"第{row+1}行数据内容为：{value}")
                result.append(f"第{row}行数据内容为：{value}" + "\n")
            with open('logs.txt','a',encoding='utf-8') as f:
                f.writelines(result)
        except:
            # 报错先回滚
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()
    #  1.3、删除指定一条数据
    def deleteRow(self,name):
        self.connect()
        try:
            self.cursor.execute(f'select * from stu where name="{name}"')
            result = self.cursor.fetchall()
            if result:
                self.cursor.execute(f'delete from stu where name="{name}"')
                self.db.commit()
                print("删除：%s成功！"%name)
                with open('logs.txt', 'a', encoding='utf-8') as f:
                    f.write("当前时间为：" + str(datetime.now()) +f"当前执行删除一条数据操作，成功！删除内容是：{name}"+"\n")
            else:
                print("没有这个信息，删除失败！")
        except:
            # 报错先回滚
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()
    # 1.4、封装批量删除方法，可以删除多条
    def deleteRows(self,*names):
        self.connect()
        result = ["当前时间为：" + str(datetime.now()) +f"当前执行删除批量数据操作"+"\n"]
        try:
            for name in names:
                self.cursor.execute(f'delete from stu where name="{name}"')
                print(f"当前删除的对象是：{name}")
                result.append(f"当前删除的对象是：{name}" + "\n")
            self.db.commit()
            with open('logs.txt','a',encoding='utf-8') as f:
                f.writelines(result)
        except:
            # 报错先回滚
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()
    # 1.5、可以指定增加单独一条数据到表里
    def insertRow1(self,name,age,address,ssn):
        # 姓名、年龄、家庭住址、身份证号码
        self.connect()
        try:
            sql_obj = f"insert into stu(name,age,address,ssn) values('{name}','{age}','{address}','{ssn}')"
            self.cursor.execute(sql_obj)
            print("当前新增的信息，姓名为：{}，年龄是：{}，住址是：{}，身份证号码是：{}".format(name, age, address, ssn))
            self.db.commit()
            with open('logs.txt', 'a', encoding='utf-8') as f:
                f.write("当前时间为：" + str(datetime.now()) + f"当前执行新增一条数据操作，成功！新增内容是：{name}" + "\n")
        except:
            # 报错先回滚
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()

# if __name__ == '__main__':
#     s1 = Stu()
    # 新增数据
    # s1.insertRow()
    # 再去查询
    # s1.searchAll()
    # 删除一条
    # s1.deleteRow('迟宁')
    # 删除多条
    # s1.deleteRows('王欣','吴浩','陈利')
    # 插入一条
    # s1.insertRow1('张三','99','沈阳','2090890222131245')


# 2、做一个学生点名系统，系统里支持：存入学生、更改学生、删除学生、点到学生姓名方法
#
# 存入学生（姓名、年龄、家庭地址、手机号）： 存入成功后，提示xxx存入成功
# 更改学生（姓名、年龄、家庭地址、手机号）：可以修改学生内容的任意一个字段
# 删除学生：删除的学生将不在展示
# 展示全部学生：可以看到全部的学生姓名
# 学生姓名：随机抽取任意一个存在的学生信息，然后打印：到！。举例： 刘闯到！
#
# 以上内容，需要连接数据库，每次的数据都需要增、删、改、查去做
class student(DB):
    def insertStu(self,name,age,address,phone):
        self.connect()
        try:
            self.cursor.execute(f'insert into stu1(name,age,phone,address) values("{name}","{age}","{phone}","{address}")')
            print(f"插入数据，姓名：{name}，年龄：{age}，手机号：{phone}，地址：{address} 成功！")
            self.db.commit()
        except:
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()

    def updateStu(self,old_name,new_name,age,address,phone):
        self.connect()
        try:
            self.cursor.execute(f"update stu1 set name='{new_name}',age='{age}',address='{address}',phone='{phone}' where name='{old_name}'")
            print(f"修改数据，姓名：{old_name}，新名字为：{new_name}，年龄：{age}，手机号：{phone}，地址：{address} 成功！")
            self.db.commit()
        except:
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()

    def deleteStu(self,name):
        self.connect()
        try:
            self.cursor.execute(f'select * from stu1 where name = "{name}"')
            r = self.cursor.fetchall()
            if r:
                self.cursor.execute(f'delete from stu1 where name = "{name}"')
                self.db.commit()
                print(f'删除{name}成功')
            else:
                print(f"删除失败,{name}不存在")
        except:
            self.db.rollback()
            traceback.print_exe()
        finally:
            self.close()

    def showAll(self):
        self.connect()
        try:
            self.cursor.execute('select * from stu1')
            r = self.cursor.fetchall()
            for row,value in enumerate(r):
                print(f"第{row}行的数据为：{value}")
        except:
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()

    def dianming(self):
        self.connect()
        try:
            self.cursor.execute('select * from stu1')
            r = self.cursor.fetchall()
            row = random.choice(r)
            print(f'{row["name"]}到！')
        except:
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()

# if __name__ == '__main__':
#     s1 = student()
#
#     s1.insertStu('张六',22,'吉林','2315644314')
#
#     s1.updateStu('张六','张晓柳',29,'吉林吉林','16868891')
#
#     s1.deleteStu('张晓柳')
#
#     s1.showAll()
#
#     s1.dianming()


# 3、类作业，统计镰刀和斧头的数量，要使用类方法
liandao = 0
futou = 0
class tools:
    def __init__(self,tool):
        global liandao,futou
        self.tool = tool
        if self.tool == '镰刀':
            liandao += 1
        elif self.tool == '斧头':
            futou += 1

if __name__ == '__main__':
    tools('镰刀')
    tools('斧头')

    print(liandao)



# 4、新建学生成绩管理系统，随机生成100个 学生信息插入到数据库：
# 学生信息组成：学号、学生姓名、英语成绩、数学成绩、语文成绩、班级号（班级号有：1809A，1809B，1810A，1810B）
#
# 成绩划分为：优秀，良好，中等，及格，不及格。良好比中等好。
#
# 优秀：90—100之间（包括90）
# 良好：80-89
# 中等：70-79
# 及格：60-69
# 不合格：分数低于60分。
#
# 成绩管理系统提供以下方法：
# 《1》 查询所有英语成绩为优秀的、良好的、中等、及格和不合格的学生姓名和班级号
# 《2》 查询1809A，1809B，1810A，1810B每个班级的数学成绩，并且是降序返回
# 《3》 查询1809A，1809B，1810A，1810B每个班级的总人数，并且由大到小排序返回
# 《4》 查询英语、数学、语文成绩不合格的学生姓名和对应的班级号，按照不合格的人数，由大到小排序





# 5、定义一个图书管理系统类，图书可以新增、修改、删除，要求新增、修改、删除的图书，都要出现在数据库中
# 新增：图书名、作者名称、新建年月日
# 修改：图书名、作者名称、新建年月日
# 删除：图书删掉，且不在展示
# 查看：全量查询、精确查询、模糊查询需要用户传入形参来控制返回结果
class library(DB):
    def add_book(self,name,writer,date):
        self.connect()
        try:
            self.cursor.execute(f'insert into library1(name,writer,date) value("{name}","{writer}","{date}")')
            print(f"插入数据，新增的图书名称为{name}，作者是{writer}，新建年月日为{date}")
            self.db.commit()
        except:
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()
# create table library1(id int primary key auto_increment,name varchar(30),writer varchar(30),date varchar(30);
    def update_book(self,old_name,new_name,writer,date):
        self.connect()
        try:
            self.cursor.execute(f"update library1 set name='{new_name}',writer='{writer}',date='{date}'")
            print(f"修改数据，书名：{old_name},新名字：{new_name},作者是{writer}，创建时间{date}")
            self.db.commit()
        except:
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()

    def delete_book(self,name):
        self.connect()
        try:
            self.cursor.execute(f'select * from library1 where name = "{name}"')
            r = self.cursor.fetchall()
            if r:
                self.cursor.execute(f'delete from library1 where name = "{name}"')
                self.db.commit()
                print("删除成功")
            else:
                print(f"删除失败，{name}不存在")
        except:
            self.db.rollback()
            traceback.print_exc()
        finally:
            self.close()

    # 查看：全量查询、精确查询、模糊查询需要用户传入形参来控制返回结果
    def select_book(self):
        type = input("请输入你要做的操作：①全部查询②精确③模糊")
        self.connect()
        if type == '1' or type == 1: # 全量查询
            self.cursor.execute('select * from library1')
            result = self.cursor.fetchall()
            if result:
                for row,value in enumerate(result):
                    print(f"当前是：{row+1}行，内容为：{value}")
            else:
                print("当前没有任何书籍内容")
        elif type == '2' or type ==2:
            name = input("请输入你要查询的书籍名称")
            self.cursor.execute('select * from libray1 where name="{}"'.format(name))
            result = self.cursor.fetchall()
            if result:
                print("书籍信息查到了，为：{}".format(result))
            else:
                print("信息没有，空的数据")
        elif type == '3' or type ==3:
            name = input("请输入你所知道的书籍信息")
            self.cursor.execute(f"select * from library1 where name like '%{name}%'")
            result = self.cursor.fetchall()
            if result:
                print(f"书记找到了，为{result}")
            else:
                print("书籍没找到！")


if __name__ == '__main__':
    s1 = library()

    # s1.add_book('杀死一只知更鸟','1','2002.06.26')
    # s1.add_book('霍乱时期的爱情', '2', '2002.06.26')

    # s1.update_book('杀死一只知更鸟','霍乱时期的爱情','1','2002.06.26')

    # s1.delete_book("霍乱时期的爱情")

    # 想要全部查询
    s1.select_book()
